package
{
	import caurina.transitions.Tweener;
	import caurina.transitions.properties.CurveModifiers;
	
	import flash.display.BitmapData;
	
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.video.StreamingVideoPlayer;
	
	public class video3D extends DisplayObject3D
	{
		
		private var streamingVideo:StreamingVideoPlayer;	//Neues 2D Video
		private var videoBMP:BitmapData;					//Bitmapdata - Soll Video auslesen
		private var videoPlane:Plane;						//Soll das Video aufnehmen
		private var infoPlane:Plane;						//Informationen zu einem Video
		private var videoMaterial:BitmapMaterial;			//Material für die videoPlane
		private var planeHolder:Array;						//Enthält alle Planes
		private var planeMargin:Number = 150;				//Abstand zwischen den Planes
		
		/**
		 * Hier wird die Videobox initialisiert
		 * @param dbID Soll die Datenbank symbolisieren aus der später ausgelesen wird
		 */
		public function video3D(dbID:int = 0)
		{
			init();
		}
		
		/**
		 * Neues Video mit Infoplanes erstellen
		 */
		private function init():void{
			
			//BezierKurven für den Tweener erlauben
			CurveModifiers.init();
			
			//merken welche Planes existieren
			planeHolder = new Array();
			
			//Neues Video
			//Die Videomasse kommen nachher aus der DB
			streamingVideo = new StreamingVideoPlayer(null,"beamer.flv",15,640,368);
			//Bitmapdata mit der selben Auflösung wie das Video
			videoBMP = new BitmapData(640,368);
			//Erstellen des Materials für den Plane - BitmapMaterial mit Video		
			videoMaterial = new BitmapMaterial(videoBMP);
			//Neues Plane mit 20x20 Polygonen
			videoPlane = new Plane(videoMaterial,640,368,20,20);
			//Plane anzeigen
			addPlane(videoPlane);
			
			//Material der Infoplanes
			var infoMat:ColorMaterial = new ColorMaterial(0xffffff);
			//Von 2 Seiten sichtbar
			infoMat.doubleSided = true;
			
			//Neue Dummy Infoplanes mit Zufallsfarbe erstellen
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			addPlane(new Plane(new ColorMaterial(Math.random()*0xffffff),640,368,10,10));
			
			//Start des Durchtauschends der Planes
			togglePosition();
			
		}
		
		/**
		 * Plane wird in der VideoBox hinzugefügt und in das Planearray eingefügt.
		 * Die Position des neuen Planes wird neu errechnet.
		 * @param newPlane Das anzuzeigende Plane
		 */
		private function addPlane(newPlane:Plane):void{
			//Je nach Anzahl der bereits vorhanden Plane Startpos ausrechnen
			newPlane.moveForward(planeHolder.length * planeMargin);
			
			//Von 2 Seiten sichtbar
			newPlane.material.doubleSided = true;
			
			//Plane wird ins Array gepackt. Es wird so beim toggeln beachtet
			planeHolder.push(newPlane);
			
			//Sichtbar machen
			addChild(newPlane);
		}
		
		/**
		 * Der Planeholder wird durchlaufen und der vorderste Plane nach hinten 
		 * getauscht. Die anderen Planes rutschen nach vorne.
		 */
		private function togglePosition():void{
			
			//Es wird das vorderste Plane aus dem Array ausgeschnitten
			var tmpPlane:Plane = planeHolder.splice(0,1).pop();
	
			//Die restlichen Planes im Holder werden relative zu Ihrer Position 
			//nach vorne geholt
			
			for each(var forwardPlane:Plane in planeHolder) {
				Tweener.addTween(forwardPlane,{z:forwardPlane.z - planeMargin,time:3});
			}
			
			var myPath:Array = new Array();
			myPath.push({x:0, y:500, z:(-planeMargin*2)});
			myPath.push({x:0, y:500, z:planeHolder.length * planeMargin + (planeMargin * 2)});
			
			//Der vorderste Plane wird nach hinten geschoben		
			Tweener.addTween(
				tmpPlane,
				{	
					x:0,
					y:0,
					z:planeHolder.length * planeMargin,
					time:3,
					_bezier:myPath,
					transition:"linear",
					//Wenn der Tween abgeschlosssen ist
					onComplete:function():void{
						//Der abgeschnittene Plane wird hinten ans Array angebaut
						planeHolder.push(this);
						//Ein neues Tauschen wird angestoßen
						togglePosition();	
					}
				}
			);
		}
		
		/**
		 * In jedem Frame muss das Videomaterial neu ausgelesen werden
		 */
		public function update():void{
			videoBMP.draw(streamingVideo);
			videoMaterial.updateBitmap();	
		}
	}
}